package com.baosight.xdata.monitor.utils;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.HashMap;
import java.util.Map;

public class JedisUtil {

    private static JedisUtil jedisUtil;

    private JedisUtil() {
    };

    public static JedisUtil getInstance() {
        if (jedisUtil == null) {
            synchronized (JedisUtil.class) {
                if (jedisUtil == null) {
                    jedisUtil = new JedisUtil();
                }
            }
        }
        return jedisUtil;
    }

    //Jedis的连接池
    private static Map<String, JedisPool> maps = new HashMap<>();

    private static JedisPool getPool(String ip, int port) {
        String key = ip + ":" + port;
        JedisPool pool = null;
        if (!maps.containsKey(key)) {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxIdle(RedisConfig.MAX_IDLE);
            config.setMinIdle(RedisConfig.MIN_IDLE);
            config.setMaxTotal(RedisConfig.MAX_TOTAL);
            config.setMaxWaitMillis(RedisConfig.MAX_WAIT);
            config.setTestOnBorrow(true);
            config.setTestOnReturn(true);

            pool = new JedisPool(config, ip, port, RedisConfig.TIMEOUT);
            maps.put(key, pool);
        } else {
            pool = maps.get(key);
        }
        return pool;
    }

    public Jedis getJedis(String ip, int port) {
        Jedis jedis = null;
        int count = 0;
        do {
            try {
                jedis = getPool(ip, port).getResource();
            } catch (Exception e) {
                getPool(ip, port).close();
            }
        } while (jedis == null && count < RedisConfig.RETRY_NUM);
        return jedis;
    }

    public void closeJedis(Jedis jedis, String ip, int port) {
        if (jedis != null) {
            getPool(ip, port).close();
        }
    }

    public static class RedisConfig {
        //最大实例总数
        public static int MAX_TOTAL = 150;

        //最大空闲连接数, 默认8个
        public static int MAX_IDLE = 100;

        //最小空闲连接数, 默认8个
        public static int MIN_IDLE = 10;

        //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
        public static int MAX_WAIT = 10000;

        public static int TIMEOUT = 10000;

        public static int RETRY_NUM = 5;

        public RedisConfig() {
        };
    }
}
